import type { UseBpmnModelerReturnType, BpmnModelerMethods, BpmnProps, ReturnMethods, BpmnMethods } from '../typing';
import { ref, onUnmounted, unref, getCurrentInstance, reactive, watchEffect, nextTick, toRaw, computed, Ref, markRaw } from 'vue';
import { isProdMode } from '/@/utils/env';
import { isFunction } from '/@/utils/is';
import { isEqual } from 'lodash-es';
import { tryOnUnmounted } from '@vueuse/core';
import { error } from '/@/utils/log';

import BpmnModeler from 'bpmn-js/lib/Modeler'
import customTranslate from '../customTranslate/customTranslate'
import activitiModdleDescriptors from '/public/resource/bpmn/activiti-moddel.json'

// 导入一下有关于bpmn-js的字体库以及样式文件
import 'bpmn-js/dist/assets/diagram-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
// 右侧属性面包样式
import 'bpmn-js-properties-panel/dist/assets/properties-panel.css'

// 两个属性面板相关模块
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule, CamundaPlatformPropertiesProviderModule } from 'bpmn-js-properties-panel'


const dataTransfer = reactive<any>({});

const bpmnModeler = ref();
let scale = 1

/**
 * @description: Applicable to independent modal and call outside
 */
export function useBpmnModeler(): UseBpmnModelerReturnType {
  console.log("useBpmnModeler...")
  const bpmnInstanceRef = ref<Nullable<BpmnModelerMethods>>(null);
  const currentInstance = getCurrentInstance();
  const uidRef = ref<string>('');
  const loadedRef = ref<Nullable<boolean>>(false);

  const getBpmnInstance = async () => {
    const instance = unref(bpmnInstanceRef);
    if (!instance) {
      error('useModalInner instance is undefined!');
    }
    await nextTick();
    return instance as BpmnModelerMethods;
  };

  const register = (bpmnInstance: BpmnMethods, uuid: string) => {
    console.log("useBpmnModeler register...")

    isProdMode() && tryOnUnmounted(() => {
      bpmnInstanceRef.value = null;
      loadedRef.value = null;
    });
    uidRef.value = uuid;

    // bpmnInstance.get 
    loadedRef.value = true;

    const bpmnContainer = (bpmnInstance.getBpmnContainer()) as HTMLElement
    console.log('useBpmnModeler register', bpmnContainer)

    bpmnInstanceRef.value = bpmnInstance;
  };

  const initBpmnModeler = async () => {
    try {
      const bpmnInstance = await getBpmnInstance()
      console.log(bpmnInstance)
      await nextTick()
      const bpmnContainer = (await bpmnInstance.getBpmnContainer()) as HTMLElement
      console.log('initBpmnModeler', bpmnContainer)

    } catch (e) {
      console.error(e)
    }

    // console.log('bpmnContainer', bpmnContainer)
    // const customTranslateModule = {
    //   translate: ['value', customTranslate],
    // }
    // 加markRaw去除双向绑定作用域
    // bpmnModeler.value = markRaw(
    //   new BpmnModeler({
    //     container: bpmnContainer,
    //   })
    // )
    // console.log('初始化BpmnModeler', unref(bpmnModeler))
  }



  watchEffect(async () => {
    // alert('useBpmnModeler watchEffect...')
  });

  const importXML = (xml: string) => {
    return new Promise((resolve, reject) => {
      if (bpmnModeler.value) {
        bpmnModeler.value.importXML(xml).then(result => {
          resolve(result);
          bpmnModeler.value.get('canvas').zoom('fit-viewport', 'auto');
        });
      } else {
        reject('BpmnModeler对象尚未定义！');
      }
    });
  }

  const redoBpmn = () => {
    bpmnModeler.value.get('commandStack').redo()
  }

  const undoBpmn = () => {
    bpmnModeler.value.get('commandStack').undo()
  }

  const zoomBpmn = (radio) => {
    const newScale = !radio ? 1.0 : scale + radio
    bpmnModeler.value.get('canvas').zoom(newScale)
    scale = newScale
  }

  const beforeUpload = (file) => {
    // this.uploadBpmnFileList = [];
    openBpmn(file)
    return false
  }

  const openBpmn = (file) => {
    const reader = new FileReader()
    // 读取File对象中的文本信息，编码格式为UTF-8
    reader.readAsText(file, 'utf-8')
    reader.onload = () => {
      // 读取完毕后将文本信息导入到Bpmn建模器
      // createNewDiagram(reader.result);
    }
    return false
  }

  const downloadXml = () => {
    bpmnModeler.value.saveXML({ format: true }, (err, data) => {
      if (!err) {
        const xml = data.replace(/camunda.org\/schema\/1.0\/bpmn/ig, "activiti.org/bpmn").replace(/camunda/ig, "activiti");
        // 获取文件名
        const name = `${getFilename(xml)}.bpmn`
        // 将文件名以及数据交给下载方法
        download({ name: name, data: xml })
      }
    })
  }

  const downloadSvg = () => {
    bpmnModeler.value.saveXML({ format: true }, (err, data) => {
      if (!err) {
        const xml = data.replace(/camunda.org\/schema\/1.0\/bpmn/ig, "activiti.org/bpmn").replace(/camunda/ig, "activiti");
        // 获取文件名
        const name = `${getFilename(xml)}.svg`

        // 从建模器画布中提取svg图形标签
        let context = ''
        const djsGroupAll = bpmnModeler.value?.querySelectorAll('.djs-group')
        if (djsGroupAll) {
          djsGroupAll.forEach((djsGroup) => {
            context += djsGroup.innerHTML
          })
        }
        // 获取svg的基本数据，长宽高
        const viewport: any = bpmnModeler.value?.querySelector('.viewport')
        console.log('获取svg的基本数据，长宽高', viewport);

        // 将标签和数据拼接成一个完整正常的svg图形
        const svg = `<svg
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            width="${viewport?.width}"
            height="${viewport?.height}"
            viewBox="${viewport?.x} ${viewport?.y} ${viewport?.width} ${viewport?.height}"
            version="1.1"
            >
            ${context}
          </svg>`
        // 将文件名以及数据交给下载方法
        download({ name: name, data: svg })
      }
    })
  }

  const download = ({ name = 'diagram.bpmn', data }) => {
    console.log(data)
    // 把输就转换为URI，下载要用到的
    const encodedData = encodeURIComponent(data)

    if (data) {
      const downloadLink = document.createElement('a')
      // 将数据给到链接
      downloadLink.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData
      // 设置文件名
      downloadLink.download = name
      // 触发点击事件开始下载
      downloadLink.click()
      downloadLink.remove()
    }
  }

  const getFilename = (xml) => {
    let start = xml.indexOf('process')
    let filename = xml.substr(start, xml.indexOf('>'))
    filename = filename.substr(filename.indexOf('id') + 4)
    filename = filename.substr(0, filename.indexOf('"'))
    return filename
  }

  return [
    register,
    {
      initBpmnModeler, importXML, redoBpmn, undoBpmn, zoomBpmn, downloadXml, downloadSvg,
      savaBpmn: function (): void {
        throw new Error('Function not implemented.');
      },
      setBpmnProps: function (props: Partial<BpmnProps>): void {
        throw new Error('Function not implemented.');
      },
      getBpmnContainer: function (): HTMLElement | undefined {
        throw new Error('Function not implemented.');
      }
    },
  ];
};
